import {Injectable} from '@angular/core';
import {User} from '../../modules/user/class/user';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {CookieService} from 'ngx-cookie-service';
import {environment} from '../../../environments/environment';
import {Auth} from './auth';
import {Observable} from 'rxjs/Observable';
import {catchError, map} from 'rxjs/operators';

@Injectable()
export class AuthService {
  COOKIE_USER = 'user';
  COOKIE_AUTH = 'auth';

  constructor(
    private http: HttpClient,
    private cookieService: CookieService,
  ) {
  }

  setUser(user: User) {
    this.cookieService.set(this.COOKIE_USER, JSON.stringify(user));
  }

  /**
   * 获取当前用户信息
   * @returns {User}
   */
  getUser(): User {
    return !!this.cookieService.get(this.COOKIE_USER) ? JSON.parse(this.cookieService.get(this.COOKIE_USER)) : null;
  }

  setAuth(auth: Auth) {
    this.cookieService.set(this.COOKIE_AUTH, JSON.stringify(auth));
  }

  getAuth(): Auth {
    return !!this.cookieService.get(this.COOKIE_AUTH) ? JSON.parse(this.cookieService.get(this.COOKIE_AUTH)) : null;

  }


  /**
   * 注销
   */
  logout(): void {
    this.cookieService.deleteAll();
    this.logoutPage();
  }

  /**
   * 跳转到登陆页
   */
  loginPage(): void {
    window.location.href = environment.oauthUrlPrefix + '/oauth/authorize' +
      '?response_type=code&client_id=client&redirect_uri=' + encodeURIComponent(location.href.split('?')[0]);
  }

  logoutPage() {
    window.location.href = environment.oauthUrlPrefix + '/logout';
  }

  /**
   * 身份认证
   * @returns {boolean}
   */
  isAuthenticated(): boolean {
    return !!this.getAuth() && this.getAuth().expires_to > new Date().getTime();
  }

  /**
   * 登录
   * @param code
   */
  login(code: string): Observable<boolean> {
    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/x-www-form-urlencoded',
        'Authorization': 'Basic ' + btoa('client:secret')
      })
    };
    return this.http.post(environment.oauthUrlPrefix + '/oauth/token?code=' + code + '&grant_type=authorization_code&redirect_uri=' +
      encodeURIComponent(location.href.split('?')[0]), {}, httpOptions).pipe(
      map(res => {
        const auth = new Auth();
        auth.access_token = res['access_token'];
        auth.jti = res['jti'];
        auth.refresh_token = res['refresh_token'];
        auth.scope = res['scope'];
        auth.token_type = res['token_type'];
        // 提前200秒避免异常
        auth.expires_to = (res['expires_in'] - 200) * 1000 + new Date().getTime();
        this.setAuth(auth);
        this.setUser(this.getUserByAuth(auth));
        return true;
      }),
      catchError(err => {
        return Observable.throw(err);
      }));
  }

  getUserByAuth(auth: Auth): User {
    const token = auth.access_token;
    const split = token.split('.');
    const user = new User(JSON.parse(atob(split[1])));
    console.log(user);
    return user;
  }
}
